package com.yanjue.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.yanjue.common.entity.IndexPageConfig;
import com.yanjue.mapper.IndexPageConfigMapper;
import com.yanjue.common.redisKey.RedisExpire;
import com.yanjue.common.redisKey.RedisHomepageKey;
import com.yanjue.common.redisKey.RedisService;
import com.yanjue.common.util.CommonUtil;
import com.yanjue.common.util.Result;
import com.yanjue.common.util.ResultUtil;
import com.yanjue.service.IndexBannerService;
import com.yanjue.service.IndexBooklistService;
import com.yanjue.service.IndexPageConfigService;
import com.yanjue.vo.IndexPageVO;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
* @author yanjue
* @description 针对表【index_page_config(精品页配置表)】的数据库操作Service实现
* @createDate 2025-01-16 12:33:44
*/
@Service
@Slf4j
public class IndexPageConfigServiceImpl extends ServiceImpl<IndexPageConfigMapper, IndexPageConfig>
    implements IndexPageConfigService {

    private static final Logger LOGGER = LoggerFactory.getLogger(IndexPageConfigServiceImpl.class);
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private IndexPageConfigMapper indexPageConfigMapper;

    @Autowired
    private IndexBannerService indexBannerService;

    @Autowired
    private IndexBooklistService indexBooklistService;

    @Autowired
    private RedisService redisService;

    /**
     * 精品页：精品页主要提供app首页数据接口，换一换、图书列表接口。所以依赖于图书中心和账户中心。
     * 包含有各种分类（榜单），展示部分榜单的书籍（可以按照评分排名（评分可以调取用户打分取avg（无法实现）））
     * 点击换一批，更换下一批本榜单的数据
     * 这里是使用banner（榜单）的内容来展示相应数据，vo：banner（相当于一个分类），banneritem（分类里的图片等对象）
     *      book（书单里的书），booklist（书单（榜单））
     *      indexPage（包含书单，banner）
     *      书籍更新 -> 删除redis -> 查在更新redis，（更新章节、创作新书、评分上升等）
     * 精品页配置表(index_page_config)
     * 这个表为精品页推荐、男生、女生的配置总表，根据page_type存储对应的banner或 booklist
     * page_type=1 即书单，page_type=2 则Banner
     * Banner轮播表(index_banner)
     * Banner轮播明细表(index_banner_item)
     * 书单配置表(index_booklist)
     * 书单配置明细表(index_booklist_item)
     *
     * @param type 类型
     * @param page
     * @param limit
     * @return
     * TODO 理想 ---> 在该页面下，有整体VO 包含榜单类型的list集合（男 女 会员书（涉及会员但是没有写·） 原创等），榜单里有书单比如（今日必读，强推，潜力新书等），每个书单里应该按照图书分类set图书集合
     *  这个傻逼表设计的 傻逼前端搞得tlj，
     */
    @Override
    public Result getIndexPageByType(Integer type, Integer page, Integer limit) {
        //1.获取key
        String key = RedisHomepageKey.getHomepageKey(type);
        log.info("page===:{}===============================",page);
        //2.读缓存获精品页的vo
        List<IndexPageVO> pageVOS = this.redisService.getHashListVal(key, page.toString(), IndexPageVO.class);
        if (pageVOS != null){
            return ResultUtil.success(pageVOS);
        }

        //3.缓存没有，读取数据库（包含读当前精品页的配置项，读书单 / banner）
        //3.1.获取配置项
        List<IndexPageConfig> pageConfigs = this.getIndexPageWithPaging(type,page,limit);
        if (CommonUtil.isEmpty(pageConfigs)){
            LOGGER.warn("当前精品页无配置项");
            return ResultUtil.success("当前请求也没有配置项");
        }

        //3.2.根据配置项里的itemID，看是具体读书单表，还是banner表，并进行copy
        pageVOS = new ArrayList<>(pageConfigs.size());
        //
        boolean okFlag = true;
        for (IndexPageConfig pageConfig : pageConfigs) {
            IndexPageVO vo = new IndexPageVO();
            BeanUtils.copyProperties(pageConfig,vo);

            //判断是书单还是banner
            switch (pageConfig.getItemType()){
                case 1:
                    //书单 书单服务调，根据书单id查数据，五随机 TODO 按理来说每次精品页的这些书单是随机的，后面都随机 客户端随机数不为null
                    vo.setBooklist(this.indexBooklistService.getIndexBooklistVO(pageConfig.getItemId(),null));
                    if(vo.getBooklist() == null){
                        okFlag = false;
                    }
                    break;
                case 2:
                    //banner banner服务调，根据id
                    vo.setBanner(this.indexBannerService.getBannerVO(pageConfig.getItemId()));
                    if (vo.getBanner() == null){
                        okFlag = false;
                    }
                    break;
                default:
                    break;
            }

            // 对应的模块值不为空，才进行添加到VO中
            if (okFlag) {
                pageVOS.add(vo);
            }

            if (!pageVOS.isEmpty()) {
                // 缓存精品页
                this.redisService.setHashValExpire(key, page.toString(), pageVOS, RedisExpire.DAY);
            }
            log.info("循环里的pageVO==:{}",pageVOS);
        }
        log.info("最终pageVO==========================:{}",pageVOS);
        return ResultUtil.success(pageVOS);
    }

    /**
     * 分页获取精品页配置
     * @param type
     * @param page
     * @param limit
     * @return
     */
    private List<IndexPageConfig> getIndexPageWithPaging(Integer type, Integer page, Integer limit) {
        page = page <= 0 ? 1 : page;
        PageHelper.startPage(page,limit);
        return this.indexPageConfigMapper.findPageWithResult(type);
    }
}

























